package org.theSeed.base.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.theSeed.base.exp.ServiceExp;
import org.theSeed.base.pojo.constant.SysConstant;

import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

@Slf4j
public class RequestUtil {
    public RequestUtil() {
    }

    public RequestUtil(Function<Supplier<String>,String> retryTemplate) {
        this.retryTemplate = retryTemplate;
    }

    /**
     * 重试工具
     */
    private static Function<Supplier<String>,String> retryTemplate = (supplier)->{
        return supplier.get();
    };

    /**
     * 无请求体请求
     * @param method
     * @param headers
     * @param url
     * @param urlParam
     * @return
     */
    public static String noBodyHttp(Method method,Map<String,String> headers, String url, Map<String,Object> urlParam){
        return retryTemplate.apply(()->{
            return request(method,headers,url,urlParam,null,false,false);
        });
    }

    /**
     * form请求体请求
     * @param method
     * @param headers
     * @param url
     * @param urlParam
     * @return
     */
    public static String formHttp(Method method,Map<String,String> headers, String url, Map<String,Object> urlParam, Map<String,Object> body){
        return retryTemplate.apply(()->{
            return request(method,headers,url,urlParam,body,true,false);
        });
    }

    /**
     * json请求体请求
     * @param method
     * @param headers
     * @param url
     * @param urlParam
     * @return
     */
    public static String jsonHttp(Method method,Map<String,String> headers, String url, Map<String,Object> urlParam, String body){
        return retryTemplate.apply(()->{
            return request(method,headers,url,urlParam,body,true,false);
        });
    }

    /**
     * http基础请求
     * @param method
     * @param headers
     * @param url
     * @param urlParam
     * @param body
     * @param formFlag
     * @param jsonFlag 响应体
     * @return
     */
    public static String request(Method method, Map<String,String> headers, String url, Map<String,Object> urlParam, Object body,boolean formFlag,boolean jsonFlag){
        String requestUrl = url;
        if (CollectionUtil.isNotEmpty(urlParam)){
            String urlParamStr = URLUtil.buildQuery(urlParam, SysConstant.defaultCharset);
            requestUrl = SeedStringUtil.concatStr(url , "?" , urlParamStr);
        }
        switch (method){
            case GET:
                return requestInit(headers, body, formFlag, jsonFlag, HttpUtil.createGet(requestUrl, true));
            case POST:
                return requestInit(headers, body, formFlag, jsonFlag, HttpUtil.createPost(requestUrl));
            case PUT:
                return requestInit(headers, body, formFlag, jsonFlag, HttpUtil.createPost(requestUrl).method(Method.PUT));
            case DELETE:
                return requestInit(headers, body, formFlag, jsonFlag, HttpUtil.createPost(requestUrl).method(Method.DELETE));
            default:
                throw new ServiceExp("暂不支持请求类型");
        }
    }

    /**
     * 初始化请求对象
     * @param headers
     * @param body
     * @param formFlag
     * @param jsonFlag
     * @param httpRequest
     */
    public static String requestInit(Map<String, String> headers, Object body, boolean formFlag, boolean jsonFlag, HttpRequest httpRequest) {
        if (ObjectUtil.isNotNull(headers))
            httpRequest.addHeaders(headers);
        if (formFlag){
            if (body instanceof Map){
                httpRequest.form((Map<String,Object>) body);
            }else{
                httpRequest.form(BeanUtil.beanToMap(body));
            }
        }
        if (jsonFlag){
            if (body instanceof String){
                httpRequest.body((String)body);
            }else{
                if (ObjectUtil.isNull(body)){
                    httpRequest.body("{}");
                }else
                    httpRequest.body(JSONUtil.toJsonStr(body));
            }
        }

        HttpResponse execute = httpRequest.execute();
        String respBody = execute.body();
        if (execute.isOk()){
            return respBody;
        }else
            log.info("请求异常:响应信息为{}", respBody);
            throw new  ServiceExp("请求失败");
    }
}
